package com.example.aiagent.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.example.aiagent.app.LoveApp;
import com.example.aiagent.app.WorkApp;
import com.example.aiagent.common.BaseResponse;
import com.example.aiagent.constant.AiConstant;
import com.example.aiagent.demo.invoke.VisionInvoke;
import com.example.aiagent.enums.ChatHistoryMessageTypeEnum;
import com.example.aiagent.exception.ErrorCode;
import com.example.aiagent.exception.ThrowUtils;
import com.example.aiagent.model.entity.User;
import com.example.aiagent.service.AppService;
import com.example.aiagent.service.ChatHistoryService;
import io.reactivex.Flowable;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.time.Duration;
import java.util.Objects;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@Service
public class AppServiceImpl implements AppService {

    private static final Logger log = LoggerFactory.getLogger(AppServiceImpl.class);
    @Resource
    private LoveApp loveApp;
    @Resource
    private WorkApp workApp;


    @Resource
    private ChatHistoryService chatHistoryService;

    public String doChatSync(String message, Long appId, User loginUser, Long aiId) {
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
        // 调用AI前，先保存用户信息到数据库中
        chatHistoryService.addChatMessage(appId, message, ChatHistoryMessageTypeEnum.USER.getValue(), loginUser.getId());
        // 调用AI生成内容
        String content = null;
        if (Objects.equals(aiId, AiConstant.DASH_SCOPE)) {
            content = loveApp.doChat(message, appId);

        } else {
            content = workApp.doChat(message, appId);
        }
        //存入数据库
        chatHistoryService.addChatMessage(appId, content, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
        return content;
    }

    /**
     * AI 基础对话（支持多轮对话记忆）,SSE输出
     * @param message
     * @param appId
     * @return
     */
    public Flux<String> doChatWithStream(String message, Long appId, User loginUser, Long aiId) {
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
        // 调用AI前，先保存用户信息到数据库中
        chatHistoryService.addChatMessage(appId, message, ChatHistoryMessageTypeEnum.USER.getValue(), loginUser.getId());
        // 调用AI对话,收集返回的对话信息
        Flux<String> contentFlux = null;
        if (Objects.equals(aiId, AiConstant.DASH_SCOPE)) {
            contentFlux = loveApp.doChatWithStream(message, appId);
        } else {
            contentFlux = workApp.doChatWithStream(message, appId);
        }
        // 将AI的信息保存到数据库中
        StringBuilder aiResponseBuilder = new StringBuilder();
        return contentFlux
                .map(chunk -> {
                    // 收集AI响应内容
                    aiResponseBuilder.append(chunk);
                    return chunk;
                })
                .doOnComplete(() -> {
                    // 流式响应完成后，添加AI消息到对话历史
                    String aiResponse = aiResponseBuilder.toString();
                    if (StrUtil.isNotBlank(aiResponse)) {
                        chatHistoryService.addChatMessage(appId, aiResponse, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
                    }
                })
                .doOnError(error -> {
                    // 如果AI回复失败，也要记录错误消息
                    String errorMessage = "AI回复失败: " + error.getMessage();
                    chatHistoryService.addChatMessage(appId, errorMessage, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
                });
    }

//    public Flux<String> doChatSSE(String message, Long appId) {
//        Flux<String> content = chatClient.prompt()
//                .user(message)
//                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, appId)
//                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
//                .stream()
//                .content();
//        return content;
//    }

    public int deleteApp(Long chatId, User loginUser) {
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
        if (chatId == null) {
            return 0;
        }
        int result = 0;
        try {
            loveApp.deleteChat(chatId);
            result = chatHistoryService.deleteChatMessage(chatId);
        } catch (Exception e) {
            log.error("删除应用关联对话历史失败: {}", e.getMessage());
        }
        return result;
    }

    @Override
    public Flux<String> doChatWithDoc(String message, Long appId, User loginUser, String fileName) {
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
        // 调用AI前，先保存用户信息到数据库中
        chatHistoryService.addChatMessage(appId, message, ChatHistoryMessageTypeEnum.USER.getValue(), loginUser.getId());
        // 调用AI对话,收集返回的对话信息
        Flux<String> contentFlux = loveApp.doWithDoc(message, appId, fileName);
        // 将AI的信息保存到数据库中
        StringBuilder aiResponseBuilder = new StringBuilder();
        return contentFlux
                .map(chunk -> {
                    // 收集AI响应内容
                    aiResponseBuilder.append(chunk);
                    return chunk;
                })
                .doOnComplete(() -> {
                    // 流式响应完成后，添加AI消息到对话历史
                    String aiResponse = aiResponseBuilder.toString();
                    if (StrUtil.isNotBlank(aiResponse)) {
                        chatHistoryService.addChatMessage(appId, aiResponse, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
                    }
                })
                .doOnError(error -> {
                    // 如果AI回复失败，也要记录错误消息
                    String errorMessage = "AI回复失败: " + error.getMessage();
                    chatHistoryService.addChatMessage(appId, errorMessage, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
                });
    }

    @Override
    public Flux<String> doChatWithImg(String message, Long appId, User loginUser, String url) throws NoApiKeyException, UploadFileException, IOException {
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
        // 调用AI前，先保存用户信息到数据库中
        chatHistoryService.addChatMessage(appId, message, ChatHistoryMessageTypeEnum.USER.getValue(), loginUser.getId());
        // 调用AI对话,收集返回的对话信息
        VisionInvoke visionInvoke = new VisionInvoke();
        String content = visionInvoke.simpleMultiModalConversationCall(message, appId, url);
        // 将AI响应的内容保存到数据库中
        chatHistoryService.addChatMessage(appId, content, ChatHistoryMessageTypeEnum.AI.getValue(), loginUser.getId());
        return convToFlux(content);
    }

    // 只需要将文本内容传给dify
    @Override
    public String dotextToAudio(String message, Long appId, Long aiId) {
        // 调用AI前，先保存用户信息到数据库中
//        chatHistoryService.addChatMessage(appId, message, ChatHistoryMessageTypeEnum.USER.getValue(), loginUser.getId());
        // 调用AI对话,收集返回的对话信息
        String content = null;
        if (Objects.equals(aiId, AiConstant.DASH_SCOPE)) {
            content = loveApp.doChat(message, appId);

        } else {
            content = workApp.doChat(message, appId);
        }
        // 将AI的信息保存到数据库中
//        StringBuilder aiResponseBuilder = new StringBuilder();
        return content;
    }

    private Flux<String> convToFlux(String content) {
        String[] chunks = content.split("\n");
        return Flux.fromArray(chunks)
                .delayElements(Duration.ofMillis(100)) // 每100ms发送一段
                .map(chunk -> chunk + "\n"); // 保持换行符
    }

}
